﻿using System;

namespace mklib.json
{
	public static class JsonTokenHelper
	{
		/// <summary>
		/// 是否包含结尾定义
		/// </summary>
		/// <returns><c>true</c> if is end the specified type; otherwise, <c>false</c>.</returns>
		/// <param name="type">Type.</param>
		public static bool IsEnd(JsonTokenChar type)
		{
			return type.HasFlag (JsonTokenChar.End);
		}

		/// <summary>
		/// 设置类型为结尾模式
		/// </summary>
		/// <param name="type">Type.</param>
		/// <param name="isEnd">If set to <c>true</c> is end.</param>
		public static void SetEnd(ref JsonTokenChar type, bool isEnd)
		{
			if (type == JsonTokenChar.Quote)
				type |= JsonTokenChar.End;
		}

		/// <summary>
		/// 获取字符类型
		/// </summary>
		/// <returns>The char type.</returns>
		/// <param name="c">C.</param>
		public static JsonTokenChar GetCharType(char c)
		{
			switch (c) {
			case ' ':
			case '\t':
				return JsonTokenChar.Blank;
			case '\n':
			case '\r':
				return JsonTokenChar.BreakLine;
			case ',':
				return JsonTokenChar.Comma;
			case ':':
				return JsonTokenChar.Colon;
			case '\'':
			case '"':
				return JsonTokenChar.Quote;
			case '{':
			case '[':
				return JsonTokenChar.Object;
			case '}':
			case ']':
				return JsonTokenChar.Object | JsonTokenChar.End;
			}

			if (IsNumber (c))
				return JsonTokenChar.Number;

			if (IsLetter (c))
				return JsonTokenChar.Letter;
			
			return JsonTokenChar.Invalid;
		}

		/// <summary>
		/// 为英文字母
		/// </summary>
		/// <returns><c>true</c> if is letter the specified c; otherwise, <c>false</c>.</returns>
		/// <param name="c">C.</param>
		public static bool IsLetter(char c)
		{
			return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
		}

		/// <summary>
		/// 为数字
		/// </summary>
		/// <returns><c>true</c> if is number the specified c; otherwise, <c>false</c>.</returns>
		/// <param name="c">C.</param>
		public static bool IsNumber(char c)
		{
			return c >= '0' && c <= '9' || c == '-';
		}

		/// <summary>
		/// 为直接量关键
		/// </summary>
		/// <returns><c>true</c> if is value the specified s; otherwise, <c>false</c>.</returns>
		/// <param name="s">S.</param>
		public static bool IsKeyword(string s)
		{
			if (String.IsNullOrEmpty (s))
				return false;

			int idx = JsonTokenConfig.Keywords.IndexOf (s);
			if (idx < 0)
				return false;
			return idx == 0 || JsonTokenConfig.Keywords [idx - 1] == ',';
		}

		public static bool IsBlank(char c)
		{
			return c == ' ' || c == '\t';
		}
		public static bool IsBreakLine(char c)
		{
			return c == '\n' || c == '\r';
		}

		public static bool IsBlankOrBreak(char c)
		{
			return IsBlank (c) || IsBreakLine (c);
		}

		public static bool IsBreaker(char c)
		{
			var type = GetCharType (c);
			switch (type) {
			case JsonTokenChar.Blank:
			case JsonTokenChar.BreakLine:
			case JsonTokenChar.Colon:
			case JsonTokenChar.Comma:
			case JsonTokenChar.Object:
			case JsonTokenChar.Quote:
				return true;
			}

			if (IsEnd (type))
				return true;
			
			return false;
		}

	}
}
